package com.ruoyi.tcp.messager;

import com.ruoyi.tcp.util.TcpAesUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @author 蒋翔 SY100242
 * @date 2024/8/5 17:31
 * @email SY100242@hnlens.com
 */
@Slf4j
public class CustomerMessageDecoder extends ByteToMessageDecoder {
    public static final String PROTOCOL_PREFIX = "7E04";
    public static final String PROTOCOL_SUFFIX = "7E05";

    private ByteBuf header;
    private ByteBuf ender;

    public CustomerMessageDecoder() {
        header = Unpooled.buffer();
        header.writeBytes(TcpAesUtil.hex2byte(PROTOCOL_PREFIX));
        ender = Unpooled.buffer();
        ender.writeBytes(TcpAesUtil.hex2byte(PROTOCOL_SUFFIX));
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
        if (Objects.isNull(byteBuf)) {
            return;
        }
        if (byteBuf.readableBytes() <= CustomerProtocol.PROTOCOL_SIZE_MIN) {
            return;
        }
        String s = TcpAesUtil.byte2hex(ByteBufUtil.getBytes(byteBuf));
//        log.info("customer 收的报文:{}",s);
        boolean startsWith = s.startsWith(PROTOCOL_PREFIX);
        boolean endsWith = s.endsWith(PROTOCOL_SUFFIX);
        if ( startsWith && endsWith) {
            ByteBuf decode = decode(byteBuf);
            if(Objects.nonNull(decode)) {
                byte[] dataBytes = ByteBufUtil.getBytes(decode);
                CustomerProtocol customerProtocol = new CustomerProtocol();
                byte[] channelNoBytes = new byte[2];
                System.arraycopy(dataBytes, 0, channelNoBytes, 0, 2);
                String channelNoStr = TcpAesUtil.byte2hex(channelNoBytes);
                Long channelNo = Long.parseLong(channelNoStr, 16);


//                byte[] data = new byte[dataBytes.length - 2];
//                System.arraycopy(dataBytes, 2, data, 0, dataBytes.length - 2);

                customerProtocol.setChannelNo(channelNo);
                customerProtocol.setEncryptData(dataBytes);
                customerProtocol.setChannelId(ctx.channel().id());
                out.add(customerProtocol);
            }
        }
    }




    public ByteBuf decode(ByteBuf byteBuf) {
        //包头起始位置
        int sliceStart = 0;
        //包头结束位置
        int sliceEnd = 0;
        //数据
        ByteBuf frame;
        if (null != header) {
            //如果存在包头
            int startIndex = ByteBufUtil.indexOf(header, byteBuf);
//            if (startIndex > -1 && startIndex < byteBuf.capacity()) {
//                //舍弃包头
//                byteBuf.readBytes(startIndex + 2);
//            }
            sliceStart = startIndex + 2;
            byteBuf.readerIndex(sliceStart);
        }
        if (null != ender) {
            //如果存在包尾
            int endIndex = ByteBufUtil.indexOf(ender, byteBuf);
            //保存包尾的下标
            sliceEnd = endIndex;
            //找到包尾并且包尾在包头后面
            if (endIndex > -1 && endIndex > sliceStart && endIndex < byteBuf.capacity()) {
                assert header != null;
                int length = endIndex - sliceStart - header.readableBytes();
                //获取数据
                frame = byteBuf.slice(sliceStart - 2 + header.readableBytes(), length + 2);
                //将reader索引放到包尾后面
//                byteBuf.skipBytes(sliceEnd - sliceStart + ender.readableBytes());
                byteBuf.readBytes(sliceEnd - sliceStart + ender.readableBytes());
                return frame;
            }
        }
        //去除无用数据
        if (sliceEnd == -1) {
            byteBuf.skipBytes(byteBuf.readableBytes());
        }
        return null;
    }
}
